# coding=utf8
import codecs
# simply vCard parser, 
# currently only handle, names, mails and phones

# license: GPL
# author: Pavel Nemec <pnemec@suse.cz>
# 2007-06-29 HACK WEEK

class ReadVcard:

    list # list of filled contacts  
    file="" #name of file
    def __init__(self):
        self.files=[]
        self.newFiles=[]
        self.list=[]
        self.parsed="false"
    def addFile(self, file):
        print "RVC. addingFile: ",file
        self.newFiles.append(file)
        self.parsed="false"
    def parseAllFiles(self):
        self.list=[]
        self.newFiles+=self.files
        self.files=[]
        self.pardsed="false"
        self.parseNewFiles()
        
    def parseNewFiles(self):
        
        for file in self.newFiles:
            try:
					fr = codecs.open(file,'r', encoding='utf-8')
                    #fr = open(file, 'r')
            except IOError:
                print 'Error:  Couldn\'t parse file: .', file
                continue;
            print "going parse: ", file
            line=fr.readline()
            while line!="":
                if line.startswith("BEGIN:VCARD"):
                    #PARSING NEW VCARD
                    #print "new vcard"
                    line = fr.readline()
                    c = Contact()
                    while line!="":
                        #print "\t",line
                        if line.startswith("END:VCARD"): break
                        if line.startswith("FN:"): 
                            line = line.replace("FN:","")
                            line = line.replace("\n","")
                            c.storeName(line)
                            #print "storing name: ",line
                        
                        if line.startswith("N:"):  #another format for maili
                            line = line.replace("N:","")
                            #print "have an N name ", line
                            parts = line.split(";")
                            if (len(parts)>1): c.storeName(parts[1]+ " "+ parts[0])
                            else: c.storeName(parts[0])
                            #print "storing name: ",parts[1]+ " "+ parts[0]
                        if line.startswith("EMAIL"):     
                           # print "have an email", line
                            type="Home"
                            mail= line.rpartition(':')[2] #parts[2] is mail
                            
                            if line.find("type")!=-1:
                                parts = line.partition("type=")
                                if parts[2].find(";")!=-1:
                                    type = parts[2].split(';')[0]
                                else:
                                    type = parts[2].split(':')[0]
                            if line.find("TYPE")!=-1:
#                                print "have an type"
                                parts = line.split("TYPE=")
                                if parts[1].find(";")!=-1:
                                    type = parts[1].split(';')[0]
                                else:
                                    type = parts[1].split(':')[0]
                            type = type.replace('\n',"")
                            mail = mail.replace('\n',"")
                            c.storeEmail(type,mail)
                        if line.startswith("TEL"):
                            type="Home"
                            tel= line.rpartition(':')[2] #parts[2] is tel
                            
                            #we have somethink like
                                #TEL;type=blablab;type=pref:email@email
                                #or
                                #TEL;type=blablab:email@email
                            if line.find("type")!=-1:
                                parts = line.partition("type=")
                                if parts[2].find(";")!=-1:
                                    type = parts[2].split(';')[0]
                                else:
                                    type = parts[2].split(':')[0]
                            if line.find("TYPE")!=-1:
#                                print "have an type"
                                parts = line.split("TYPE=")
                                if parts[1].find(";")!=-1:
                                    type = parts[1].split(';')[0]
                                else:
                                    type = parts[1].split(':')[0]
  #                          print "using type: ",type
                            type = type.replace('\n',"")
                            tel = tel.replace('\n',"")
                            c.storePhone(type,tel)
        
                        if line.startswith("PHOTO"):
                            pass
#                            print "have an photo: ",line, " skipping"
                        if line.startswith("X-AIM"):
                            parts=line.split(":")
                            c.storeIM("AIM",parts[len(parts)-1])
                        if line.startswith("X-ICQ"):
                            parts=line.split(":")
                            c.storeIM("ICQ",parts[len(parts)-1])
                        if line.startswith("X-messaging"):
                            #some crap like X-messaging/groupwise-All:account
                            type=line[line.find("/")+1:line.find("-All")]
                            im=line[line.rfind(":")+1:len(line)]
                            c.storeIM(type,im)
                        line=fr.readline()
                    self.list.append(c)
                   # print "end of vcard ",line
                   
                line=fr.readline()
            self.parsed="true"
            self.files+=self.newFiles;
            self.newFiles=[]
            print "parse finished, having ",len(self.list), " items"
    def search(self, chars):
        
        if self.parsed=="false":
            self.parseNewFiles()
        reti=[]
        for i in range(len(self.list)):
            contact=self.list[i];
            if contact.find(chars):
                #print " contact with name: ",contact.jmeno, " is ok"
                item=[i,contact.getId()]
                reti.append(item)
        return reti
    def getItemCount(self):
        return len(self.list)
    def getContact(self, id):
        if id> len(self.list) or id<0: 
            print "rvc error, wrong id: ",id
            return
        else: return self.list[id]
    def clear(self):
        self.files=[]
        self.newFiles=[]
        self.list=[]
            
class Contact:
    def __init__(self):
        self.jmeno=""
        self.phoneList=[]
        self.mailList=[]
        self.imList=[]
    def storeName(self, name):
        self.jmeno=name
        #print "Jmeno: ",name , "stored"
    def storeEmail(self,type, email):
        mail =[type,email]
        self.mailList.append(mail)
       # print "adding mail ",mail
    def storePhone(self,type, tel):
        phone =[type,tel]
        self.phoneList.append(phone)
        #print "adding phone ",phone
    def storeIM(self,type,im):

        imtype=[type,im]
        self.imList.append(imtype)
    def find(self,chars):
        # here is little big slow down, lovering and replacing can be done one for all
        # contact, @todo
        chars=chars.lower() # search for all posibility lower all
        chars=chars.replace(" ","") # do not let space prevent as finding what we want
#        chars = self.removeUmlauf(chars) #doesnt work yet :(
        found =False
        print "seraching for: ",chars
        #print "name: ",self.jmeno, " searching for: ", chars
        tmp=self.jmeno.lower()
        tmp=tmp.replace(" ","") #rid of white space
#        tmp=self.removeUmlauf(tmp) #doesnt work yet :(
        print "name is: ",tmp
        if tmp.find(chars)!=-1 :
          #  print self.jmeno, " found "
            found=True
            return found
        for phone in self.phoneList[:]:
            tmp=phone[0].replace(" ","")
            if tmp.find(chars)!=-1:
                found=True
                return found
            tmp=phone[1].replace(" ","")
            if tmp.find(chars)!=-1:
                found=True
                return found
        for mail in self.mailList[:]:
            tmp=mail[0].lower() #ther should be no white space in mail, we do not need to call .replace(" ","")
            if tmp.find(chars)!=-1:
                found=True
                return found
            tmp=mail[1].lower()
            if tmp.find(chars)!=-1:
                found=True
                return found
        for im in self.imList[:]:
            tmp=im[1].lower()
            if tmp.find(chars)!=-1:
                found=True
                return found
        return found
    def getId(self):
        return self.jmeno
    def toString(self):
        reti=self.jmeno+"\n"
        for phone in self.phoneList:
            reti+= "phone: ("+phone[0]+ "): "+ phone[1] +"\n"
        for mail in self.mailList:
            reti+= "mail: ("+mail[0]+ "): "+mail[1]+"\n"
        for im in self.imList:
            reti+= "im: ("+im[0]+ "): "+im[1]+"\n"
        return reti
    
    def removeUmlauf(self,chars):
        ''' ok not umlauf, but interpunction for now, expecting .lover() is allready called'''
        charsToRemove=['ž','š','č','ř','č','ď','ť','ň']
        reti=chars
        for i in charsToRemove:
            reti=reti.replace(i,"")
        return reti
def test():
    rvc  =   ReadVcard ()
    rvc.addFile("/home/thidney/Desktop/vcards4.vcf")
    rvc.addFile("/home/thidney/Desktop/addressbook.vcf")
    
    #rvc.parseAllFiles()
    search="pavel"
    list = rvc.search(search)
    print "search for: ", search, " ", len(list), " items"
    for i in list[:]:
        c = rvc.getContact(i[0])
        print c.toString()
